﻿using System;
using System.Linq;
using System.Data;
using System.Collections.Generic;

using Dynamic.Core.Types;
using Dynamic.Facades.EntLib.Data;
using Dynamic.Core.Extentions;
using Dynamic.Core.Utility;
namespace Dynamic.Core.Generation
{
    /// <summary>
    /// 通过反射生成实体
    /// </summary>
    public class MappingGenerator : GeneratorBase, IGenerator
    {
        /// <summary>
        /// 生成实体
        /// </summary>
        /// <param name="savePath"></param>
        /// <param name="generateType"></param>
        /// <param name="langrageType"></param>
        /// <param name="schema"></param>
        /// <param name="exclude"></param>
        public override void Generator(string savePath, GenerateType generateType, GenerateLanguageType langrageType, string schema, List<string> exclude)
        {
            DataSet ds = GetTables(string.Empty, null); if (ds.Tables.Count < 1)
            {
                return;
            }
            Dictionary<string, Table> tables = GetTables(ds.Tables[0]);

            foreach (Table tb in tables.Values)
            {
                T4.GeneratorMetadataEntity entity = new T4.GeneratorMetadataEntity();
                String content = entity.TransformText(tb, new Setting());
                System.IO.File.WriteAllText(savePath + tb.CleanName + ".cs", content);
            }
        }

        /// <summary>
        /// 将物理结构转化成逻辑通用结构
        /// </summary>
        /// <param name="dt"></param>
        /// <returns></returns>
        public Dictionary<string, Table> GetTables(DataTable dt)
        {
            Dictionary<string, Table> tables = new Dictionary<string, Table>();

            foreach (DataRow dr in dt.Rows)
            {
                string tn = dr["TableName"].ToString();
                if (!tables.ContainsKey(tn))
                {
                    tables[tn] = new Table();
                    tables[tn].ID = Guid.Empty.ToString();
                    tables[tn].Name = tn;
                    tables[tn].Descr = dr["TableDesc"].ToString();
                    tables[tn].Schema = dr["SchemaName"].ToString();
                }

                Column col = new Column();
                col.ID = Guid.Empty.ToString();
                col.ColumnID = dr["Column_id"].ToString();
                col.Name = dr["ColumnName"].ToString();
                col.IsPK = dr["PrimaryKey"].ToString().ParseBool();
                col.IsIdentity = dr["IsIdentity"].ToString().ParseBool();

                col.DbDataType = dr["Type"].ToString();
                col.MaxLength = Convert.ToInt32(dr["Length"]);
                col.Precision = Convert.ToInt32(dr["Precision"]);
                col.Scale = Convert.ToInt32(dr["Scale"]);
                col.CanNull = dr["NullAble"].ToString().ParseBool();
                col.Default = dr["DefaultValue"].ToString();
                col.Descr = dr["ColumnDesc"].ToString();
                
                tables[tn].Columns.Add(col);

                col.DynamicDataType = DataTypeUtility.SqlDbTypeToDynamicDataType(col);
                col.DataType = DataTypeUtility.DynamicDataTypeToCSType(col.DynamicDataType);
                
                //col.DisplayValueName = col.Descr;
                //dr["Create_Date"]
                //dr["Modify_Date"]
                //dr["IndexName"]
                //dr["IndexSort"]
                //dr["Computed"]
            }

            return tables;
        }

        /// <summary>
        /// 得到物理数据库表结构
        /// </summary>
        /// <param name="schema"></param>
        /// <param name="exclude"></param>
        /// <returns></returns>
        public DataSet GetTables(string schema, List<string> exclude)
        {
            Database db = DatabaseFactory.CreateDatabase();

            string sql = EntityConfigInfo.TableStruct;

            if (schema.Trim() != string.Empty)
            {
                sql += string.Format(" AND SchemaName='{0}'", schema);
            }

            if (exclude != null && exclude.Count > 0)
            {
                sql += string.Format(" AND ColumnName NOT IN ({0})", string.Join(",", exclude.ToArray()));
            }

            DataSet ds = db.ExecuteDataSet(CommandType.Text, sql);

            return ds;
        }
    }
}
